﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MonoTouchAutoBind
{
    class MonotouchBindContainer : MonotouchBind
    {
        private List<MonotouchBind> bindResult;
        private MonotouchBind currentBind;
        

        public virtual List<MonotouchBind> bindEngine
        {
            get
            {
                return new List<MonotouchBind>() { };
            }

        }



        public MonotouchBindContainer():base()
        {
            bindResult = new List<MonotouchBind>();
            EndString = "@end";
        }



        public override int PushCode(string code)
        {

            if (this.ParseFiniseStatus == ParseStatus.UnStart)
            {
                this.ParseFiniseStatus = ParseStatus.Processing;
                return ParseSelfStart(code);
            }

            if (code.TrimEnd().EndsWith(this.EndString))
            {
                this.ParseFiniseStatus = ParseStatus.Finished;
                currentBind = null;
                return ParseSelfEnd(code);
            }

            if (currentBind == null)
            {
                currentBind = bindEngine.Find(m => { return m.CanParse(code); });

                if (currentBind != null)
                {
                    Type bindType = currentBind.GetType();
                    MonotouchBind tmpBind = (MonotouchBind)Activator.CreateInstance(bindType);
                    bindResult.Add(tmpBind);
                    currentBind = tmpBind;
                }

            }

            if (currentBind != null)
            {
                currentBind.PushCode(code);
                if (currentBind.ParseFiniseStatus == ParseStatus.Finished)
                {
                    currentBind = null;
                }
            }
            else
            {
                ParseSelfBody(code);
            }

            return code.Length;
        }

        public virtual int ParseSelfStart(string code)
        {
            DebugOut.Instance.Print(code);
            return code.Length;
        }

        public virtual int ParseSelfBody(string code)
        {
            DebugOut.Instance.Print(code);
            return code.Length;
        }

        public virtual int ParseSelfEnd(string code)
        {
            DebugOut.Instance.Print(code);
            return code.Length;
        }

        public virtual string GenerateCSharpStart()
        {
            return "";
        }

        public override string GenerateCSharp()
        {


            StringBuilder sb = new StringBuilder();

            sb.Append(GenerateCSharpStart());
            sb.AppendLine();
            foreach (var bind in bindResult)
            {
                sb.AppendLine(bind.GenerateCSharp());
                this.DelegateCodeList.AddRange(bind.DelegateCodeList);
            }
            sb.Append(GenerateCSharpEnd());
            return sb.ToString();
        }

        public virtual string GenerateCSharpEnd()
        {
            return "";
        }
    }
}
